\subsection{Snark}

Da selve BitTorrent protokollen ikke var i centrum for vores projekt, brugte vi
Snark som det underliggende framework. Snark beskrives som  et ``lightweight
BitTorrent library'' skrevet i Java og vedligeholdes af ``Three Rings Design'' \footnote{http://www.threerings.net}. Snark bliver brugt i deres Java baseret spil ``Puzzle Pirates'' \footnote{http://www.puzzlepirates.com}.

Frameworket indeholder lige akkurat den nødvendige funktionalitet til at hente
filer ved brug af BitTorrent, dvs. der følger ikke en GUI med, men den har dog
et mindre command-line værktøj. Desuden følger der en lille tracker med. For at
starte download af en fil skal man i princippet kun lave en ny instans af \textsc{Snark}
klassen. Denne afhænger så af andre klasser bl.a. \textsc{TrackerClient/TrackerInfo} og \textsc{PeerCoordinator}. Disse er ansvarlige for få en peer liste fra trackeren, kontakte de forskellige peers og oprette og opretholde forbindelsen til disse peers ved udveksling af beskeder beskrevet i protokollen.

Som navnet antyder er \textsc{PeerCoordinator}'ens rolle at koordinere arbejdet
mellem peers. Dvs. den står for udvælgelse af pieces til download og er
ansvarlig for at skrive de modtagede pieces ud til disken, når de er fuldt
downloadet. Klassen holder på en peer list som indeholder alle de peers der er forbundet med klienten. Når nye peers kontakter klienten kommer de ind i
listen hvis handshaket går godt og hvis der er plads. Desuden hvis peerlisten
skulle gå hen og blive for lille kontakter den trackeren for at få flere peers.
I klassen foretages beslutningerne om hvilken peer bliver choket og unchoket.
Hver peer er repræsenteret af en instans af \textsc{Peer} klassen. \textsc{Peer} klassen (sammen med \textsc{PeerID} og \textsc{PeerState}) holder på alle oplysninger omkring en given peer, dvs. statistik som uploaded/downloaded bytes og dens nuværende tilstand choked/choking/interested/interesting osv. Samtidigt håndhæver den al kommunikation til den peer (sender og modtager protokol beskeder og tager beslutninger afhængigt af beskederne).

\textsc{PeerCoordinator}'en har en liste af alle de ønskede pieces
(\emph{wantedPieces} - pieces som den ikke har). Til at starte med indeholder
\emph{wantedPieces} alle dele blandet i en tilfældig orden. Systemet bruger en
random piece selection strategi til download af pieces og ét piece hentes fra
ét peer. Et piece fjernes først fra \emph{wantedPieces} når den er hentet og
dens hash er gyldig. Det medfører at et piece kan hentes fra flere peers, men
uden at de samarbejder om det. Men dette sker kun når der er få pieces tilbage i
\emph{wantedPieces} (end game). Når en peer sender klienten unchoke besked, kan
klienten gå igang med at hente fra den peer. Hvis klienten allerede er igang med
at hente et piece fra den peer fortsættes download af det piece (afsendelse af
flere piece request beskeder), hvis den ikke er igang med at hente eller den
bliver færdig med at et piece og peer er stadig villig til at uploade til os
(klienten har ikke modtaget en choke besked), spørges
\textsc{PeerCoordinator}'en hvilket piece der skal hentes, hvor der tages hensyn til hvilke pieces den peer har ved kigge på dens bitfield.

\subsubsection{Modifikationer og tilføjelser}

Vi var nød til at foretage nogle ændringer i frameworkets kildekode, for at få
systemet til at fungere. I første omgang viste det sig at Snark ikke kunne
modtage peer lister fra trackeren som var på binær form. Dette var en senere
tilføjelse til BitTorrent protokollen som blev indført, så en tracker kunne
sende mindre svar tilbage til klienterne. Snark kunne kun håndtere peer lister på ordbogs form (altså bencoded dictionaries). Vi tilføjede kode til \textsc{TrackerInfo}, som gjorde det muligt at afkode binær peer lister. Det betyder også at vi var nødt til at ændre i \textsc{Peer} klassen, mere præcist i \textsc{PeerID} klassen, som holdte på ip, port og id'et af en peer. Da peer lister på ordbogs form indeholdt peer id'et (id'et er ikke inkluderet i binær kodet lister), afhang en peers indentitet (om en peer svarer til en anden peer) af alle de tre ting, dette blev ændret til at identiteten kun afhænger af ip og port, hvilket er nok. I forlængelse af denne udvidelse til Snark, tilføjede vi også en ekstra request parameter til tracker url'en, nemlig \texttt{compact=1}, som fortæller trackeren at klienten kan modtage peer lister på binær form. Uden denne parameter nægtede nogle trackere at sende peer lister tilbage.

En anden ændring vedrørende trackere blev indført i \textsc{TrackerClient}
klassen. En udvidelse til protokollen, som Snark ikke tog hensyn til, var at
\texttt{.torrent} filen kunne indeholde en parameter \texttt{announce-list}, som
indeholdt en liste af trackers klienten kunne kontakte for at få flere peers,
hvis f.eks. den primære tracker specificeret i \texttt{.torrent} filen fejlede. Snark ignorerede denne parameter, det betød at hvis efter tre forsøg der ikke kunne skabes kontakt til den primære tracker, gik systemet ned. Vi ændrede opførelsen så istedet for at systemet gik ned efter tre forsøg, så prøvede klienten at kontakte den første tracker i \texttt{announce-list}, og efter endnu tre forsøg den anden osv. Dette betød at vi ikke behøvede være meget kræsne når vi skulle vælge hvilken \texttt{.torrent} fil vi skulle bruge.

Ud over disse fundamentale ændringer vi foretog i Snark, introducerede vi også
nogle af vores egne interfaces ind i frameworket, nemlig
\textsc{PeerCoordinatorFactory} som havde en metode, der returnerede en
\textsc{PeerCoordinator} (vi implementerede de forskellige algoritmer ved at
udvide (extend) \textsc{PeerCoordinator}), og \textsc{DownloadProgressListener}
som havde flere metoder til at overvåge fremskridtet af de downloadede pieces.
Vi tilføjede de nødvendige metoder og felter, så det var muligt at sætte implementationer af de to interfaces. Desuden ændrede vi en række felters synlighed (mest i \textsc{PeerCoordinator}), fra f.eks. private til protected, så de var synlige til subklasser.

Alle disse ændringer er dokumenteret i frameworket med kommentarer, som er tagget med \texttt{[LIMA]}.